Skip to content

CORE-680: Add C++ demo shipping service - #67

Merged
damemi merged 1 commit into
odigos-io:mainfrom
damemi:core-680-cpp-app
May 12, 2026
Merged

CORE-680: Add C++ demo shipping service#67
damemi merged 1 commit into
odigos-io:mainfrom
damemi:core-680-cpp-app

Conversation

@damemi

@damemi damemi commented Apr 9, 2026

Copy link
Copy Markdown
Member

Adds a "shipping" service in C++ which is called from frontend

damemi added a commit to odigos-io/odigos that referenced this pull request Apr 27, 2026
#### What this PR does / why we need it:
This adds `opentelemetry-ebpf-instrumentation` (OBI) as a supported
workload instrumentation distro.

The benefit of this is to provide additional coverage and offer users a
way to deploy OBI within our platform if they'd like to.

It relies on features we added upstream to OBI in
open-telemetry/opentelemetry-ebpf-instrumentation#1321
and
open-telemetry/opentelemetry-ebpf-instrumentation#1388
to support dynamic PID selection (as opposed to OBI's static service/exe
config approach).

The OBI `Instrumenter` is a single long-lived routine that handles
process events, filters/matches them based on config criteria (ie, which
PIDs we want), and attaches shared eBPF programs to those processes. The
`DynamicSelector` we added upstream provides a hook into the
`Instrumenter` to update the filter/matching criteria during runtime
without needing to restart OBI.

This adds OBI as an sdk/distro that can be used with any language. The
basic flow of the new distro is:
1. `NewOBIInstrumentationFactory()`: Initialize the OBI config and
DynamicSelector, but does not start the OBI `Instrumenter` routine yet.
This is to prevent the `Instrumenter` from running and using resources
if nothing is actually instrumented by OBI.
2. `factory.CreateInstrumentation(ctx, pid)`: If the OBI `Instrumenter`
is not started yet, this starts it and returns an `obiInstrumentation`
handle that stores that DynamicSelector and the instrumented PID. This
does not attach the PID to OBI yet.
3. `obiInstrumentation.Load()`: Uses the stored PID in the `o`
instrumentation object to call `DynamicSelector.AddPIDs(pid)` which
updates the running OBI manager to include/attach this process.
4. `obiInstrumentation.Close()`: Removes the stored PID in `o` with
`DynamicSelect.RemovePIDs(pid)` to update the OBI manager to
exclude/detach this process.

A caveat to this design is that it's difficult to _stop_ the
Instrumenter once it's started (ie, all OBI processes get uninstrumented
and we no longer need that routine) without complex async management. We
could do something like this on `Close()`:

```go
func Close() {
  f.Selector.RemovePIDs(pid)
  if len(f.Selector.GetPIDs()) == 0 {
    cancelObiCtx()
  }
}
```

But that would require a mutex, and it's possible that another OBI app
could come along in the meantime waiting to be instrumented while that
mutex is held, and the Instrumenter gets cancelled before the new app
gets added. Which would be very confusing to debug. I tried a lot of
different approaches and they were all messy. I think some more upstream
OBI changes around an actual handle on the instrumenter would help,
along with other use cases for holding a reference to the instrumenter
itself.

Overall:

* OBI Factory -- Called once at odiglet startup, runs nothing
* OBI CreateInstrumentation -- Starts OBI (if necessary) as a singleton
and creates the per-process `instrumentation` used by Odiglet
* Instrumentation Load -- Attaches the PID to the OBI singleton

Another possible upstream contribution would be a signal from OBI for
when it's actually started/running/ready to accept new PIDs which Load()
could wait on

This whole approach is slightly different from languages like Go, where
the *Odiglet* is the long lived process, so each
`CreateInstrumentation()` in Go calls the go-auto framework to load,
attach, and manage. In the case of OBI, the OBI Instrumenter handles
loading, attaching, and managing so Odiglet is a wrapped layer on top of
that for integration with our control plane.

This also adds OBI ebpf generation to the odiglet Dockerfile using the
upstream
[obi-generator[(https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/pkgs/container/obi-generator)

The OBI distro is added as its own module so it can be imported into
enterprise easier:
odigos-io/odigos-enterprise#2577 (see that PR
for details on OBI distro module)

UI Changes here: odigos-io/ui-kit#748

New C++ app in simple-demo for an e2e test here:
odigos-io/simple-demo#67

#### Changelog entry: Does this PR introduce a user-facing bug fix,
feature, dependency update, or breaking change??
<!--
This section will go in the release notes for this version. Is this
something users should be able to find easily?
If no, just write "NONE" in the release-note block below.
If yes, please add a release note in the block below describing this in
1-2 sentences for our changelog.
-->

```release-note
feat: Support opentelemetry-ebpf-instrumentation (OBI) for workload instrumentation
```
@damemi
damemi merged commit 8246f6c into odigos-io:main May 12, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants